package com.hzw.saas.service.hpc.service.impl;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.hzw.saas.api.hpc.IHpcAccountDetailService;
import com.hzw.saas.api.hpc.IHpcAccountProviderService;
import com.hzw.saas.api.hpc.IHpcAccountSearchService;
import com.hzw.saas.api.hpc.IHpcContractService;
import com.hzw.saas.api.hpc.bo.*;
import com.hzw.saas.api.hpc.enums.HpcAccountStatus;
import com.hzw.saas.api.hpc.enums.HpcProviderType;
import com.hzw.saas.api.property.IPropertyService;
import com.hzw.saas.api.property.enmus.SysDictKeyEnum;
import com.hzw.saas.common.config.util.PageParam;
import com.hzw.saas.common.config.util.PageUtils;
import com.hzw.saas.common.util.MapperUtil;
import com.hzw.saas.service.hpc.mapper.HpcAccountUserMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * @Description
 * @Date 2021/7/30 10:39 上午
 * @Created by sonam
 */
@RequiredArgsConstructor
@Service("hpcAccountSearchServiceImpl")
public class HpcAccountSearchServiceImpl implements IHpcAccountSearchService {

    private final IHpcContractService contractService;
    private final HpcAccountUserMapper hpcAccountUserMapper;
    private final IHpcAccountProviderService providerService;
    private final IHpcAccountDetailService accountDetailService;

    @Resource(name = IPropertyService.SYS_DICT_BEAN)
    private IPropertyService<SysDictKeyEnum> propertyService;

    @Override
    public IPage<HpcAccountInfoContractFullBO> pageHpcAccountInfoContractFull(PageParam pageParam,
                                                                              String keyWord,
                                                                              Integer type,
                                                                              List<String> levelIds,
                                                                              Boolean contractBound,
                                                                              List<String> slurmAccounts,
                                                                              Integer expireSort,
                                                                              Integer createSort,
                                                                              HpcProviderType hpcProviderType) {
        IPage<HpcAccountInfoFullBo> hpcAccountInfoFullBoIPage = this.pageHpcAccountInfoFull(pageParam, keyWord, type, levelIds, contractBound, slurmAccounts, expireSort, createSort, hpcProviderType);
        IPage<HpcAccountInfoContractFullBO> hpcAccountInfoFullDTOIPage = PageUtils.convert(hpcAccountInfoFullBoIPage, HpcAccountInfoContractFullBO.class);
        List<HpcAccountInfoContractFullBO> records = hpcAccountInfoFullDTOIPage.getRecords();
        if (CollectionUtils.isNotEmpty(records)) {
            records.forEach(record -> {
                // 设置合同信息
                String hpcAccountRecordId = record.getHpcAccountRecordId();
                if (StrUtil.isBlank(hpcAccountRecordId)) {
                    return;
                }

                HpcAccountStatus instance = HpcAccountStatus.instance(record.getStatus());
                record.setStatusText(instance == null ? StrUtil.EMPTY : instance.text());

                // 设置还有多少天过期
                Date expireTime = record.getExpireTime();
                if (Objects.nonNull(expireTime)) {
                    long between = DateUtil.between(expireTime, DateUtil.date(), DateUnit.DAY);
                    record.setExpireDay(between * DateUtil.compare(expireTime, DateUtil.date()));
                }

                List<HpcContractBO> hpcContracts = contractService.query(new HpcContractBO().setHpcAccountRecordId(hpcAccountRecordId));
                if (CollectionUtils.isNotEmpty(hpcContracts)) {
                    record.setHpcContracts(MapperUtil.nf().mapAsList(hpcContracts, HpcContractExtBO.class));
                    record.getHpcContracts().forEach(hpcContractDTO -> {
                        Double consumeCoreTime = accountDetailService.getHpcAccountCoreTimeSum(hpcContractDTO.getHpcAccountRecordId());
                        hpcContractDTO.setConsumeCoreTime(consumeCoreTime);
                    });
                }

                // 设置供应商类型
                String providerCode = record.getProviderCode();
                String providerId = record.getProviderId();
                if (StrUtil.isBlank(providerCode) && StrUtil.isBlank(providerId)) {
                    HpcAccountProviderBo providerBo = providerService.getById(providerId);
                    if (Objects.nonNull(providerBo)) {
                        record.setProviderCode(providerBo.getProviderCode());
                    }
                }

                record.setContractStateText(CollectionUtils.isEmpty(hpcContracts) ? "未绑定" : "已绑定");
            });
        }
        return hpcAccountInfoFullDTOIPage;
    }

    @Override
    public IPage<HpcAccountInfoFullBo> pageHpcAccountInfoFull(PageParam pageParam,
                                                              String keyWord,
                                                              Integer type,
                                                              List<String> levelIds,
                                                              Boolean contractBound,
                                                              List<String> slurmAccounts,
                                                              Integer expireSort,
                                                              Integer createSort,
                                                              HpcProviderType hpcProviderType) {
        if (type == null) {
            return new Page<>();
        }
        // 查询内容,1-未分配,2-已分配,3-已冻结,4-需要补充

        if (type == 1) {
            // 未分配的HPC账号
            return this.pageNotAllotHpcAccountInfoFull(pageParam, keyWord, null, hpcProviderType);
        } else if (type == 2) {
            // 已分配
            return this.pageAllotHpcAccountInfoFull(pageParam, keyWord, levelIds, null, contractBound, slurmAccounts, expireSort, createSort, hpcProviderType);
        } else if (type == 3) {
            // 已冻结
            return this.pageAllotHpcAccountInfoFull(pageParam, keyWord, levelIds, HpcAccountStatus.DISABLED, contractBound, slurmAccounts, expireSort, createSort, hpcProviderType);
        } else if (type == 4) {
            // 需要补充
            return this.pageNotAllotHpcAccountInfoFull(pageParam, keyWord, true, hpcProviderType);
        }

        return new Page<>();
    }

    @Override
    public IPage<HpcAccountInfoFullBo> pageAllotHpcAccountInfoFull(PageParam pageParam,
                                                                   String keyWord,
                                                                   List<String> levelIds,
                                                                   HpcAccountStatus status,
                                                                   Boolean contractBound,
                                                                   List<String> slurmAccounts,
                                                                   Integer expireSort,
                                                                   Integer createSort,
                                                                   HpcProviderType hpcProviderType) {
        return hpcAccountUserMapper.pageAllotHpcAccountInfoFull(pageParam.convert(), keyWord, levelIds, status, contractBound, slurmAccounts,
            expireSort == null ? null : expireSort == 0,
            createSort == null ? null : createSort == 0, hpcProviderType);
    }

    @Override
    public IPage<HpcAccountInfoFullBo> pageNotAllotHpcAccountInfoFull(PageParam pageParam,
                                                                      String keyWord,
                                                                      Boolean lacked,
                                                                      HpcProviderType hpcProviderType) {
        Double lackedVal = null;
        if (lacked != null && lacked) {
            try {
                lackedVal = Double.parseDouble(propertyService.getPropertyValue(SysDictKeyEnum.LACKED_HPC_TIME, "1000"));
            } catch (Exception e) {
                lackedVal = 1000d;
            }
        }
        return hpcAccountUserMapper.pageNotAllotHpcAccountInfoFull(pageParam.convert(), keyWord, lackedVal, hpcProviderType);
    }
}
